<!-- AI模板 -->
<template>
  <div class="dashboard-editor-container">
    <div>
      <div style="display:flex;justify-content:space-between;">
        <partitionTree :nodeData="nodeData" :defaultProps="defaultProps" :dialogName="'分类'"
          @handleNodeClick="handleNodeClick" @submitTemplete="submitTemplete" @deleteNode="deleteNode" ref="partitionTree"
          @toggleVisibility="toggleVisibility"></partitionTree>
        <div :style="{ width: containerWidth }" class="box"
          style="background:#fff;padding: 16px; border: 1px solid #ddd;border-radius: 4px;box-shadow: 0px 2px 4px rgba(0, 0, 0, 0.1);">
          <el-button type="primary" @click="addModer">添加软件</el-button>
          <el-table stripe border :data="tableData" style="width: 100%; margin-top: 15px">
            <el-table-column label="序号" width="80" type="index"
              :index='(index) => { return (index + 1) + (pageNum - 1) * pageSize }'> </el-table-column>
            <el-table-column label="软件分类" prop="Class" show-overflow-tooltip></el-table-column>
            <el-table-column label="软件名称" prop="Name" show-overflow-tooltip></el-table-column>
            <el-table-column label="软件描述" prop="Descp" show-overflow-tooltip></el-table-column>
            <el-table-column label="软件版本" prop="Version" show-overflow-tooltip></el-table-column>
            <el-table-column label="适用系统" show-overflow-tooltip prop="OSClass"></el-table-column>
            <el-table-column label="系统类型" show-overflow-tooltip prop="OSType">
              <template slot-scope="{row}">
                <span>{{ row.OSType ? row.OSType : '全部' }}</span>
              </template>
            </el-table-column>
            <el-table-column label="安装文件" prop="OrigFileName" show-overflow-tooltip></el-table-column>
            <el-table-column label="软件大小" prop="FileSize" show-overflow-tooltip></el-table-column>
            <el-table-column label="操作" width="210px" fixed="right">
              <template slot-scope="scope">
                <el-button type="primary" size="mini" @click="changeModer(scope.row)">修改</el-button>
                <el-button size="mini" type="danger" @click="deleteModer(scope.row)">删除</el-button>
                <el-button size="mini" type="success" @click="downloadModer(scope.row)">下载</el-button>
              </template>
            </el-table-column>
          </el-table>
          <el-pagination @size-change="handleSizeChange" @current-change="handleCurrentChange" :current-page=pageNum
            :page-size=pageSize background layout="total, prev, pager, sizes, next, jumper" :total="total">
          </el-pagination>
        </div>
      </div>
    </div>
    <el-dialog :close-on-click-modal="false" :close-on-press-escape="false" :visible.sync="moderVisible"
      :title="Action === 1 ? '添加软件' : '修改软件'" v-el-drag-dialog @close="Moder = {}" width="30%">
      <el-form label-width="100px" :rules="rules" :model="Moder" ref="Moder">
        <el-row class="ruleMain">
          <el-divider content-position="left">基本规则内容</el-divider>
          <el-form-item label="软件名称：" prop="Name">
            <el-input placeholder="请输入软件名称" maxlength="16" :disabled="Action === 2" v-model.trim="Moder.Name"></el-input>
          </el-form-item>
          <el-form-item label="软件分类：" prop="Class">
            <el-select v-model="Moder.Class" placeholder="请选择软件分类" style="width:100%">
              <el-option v-for="item in partitionList" :key="item.Name" :label="item.Name" :value="item.Name"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="软件版本：" prop="Version">
            <el-input placeholder="请输入软件版本" oninput="value=value.replace(/[^0-9a-zA-Z.]/g,'')" maxlength="32"
              v-model="Moder.Version"></el-input>
          </el-form-item>
          <el-form-item label='适用系统：' prop="OSClass">
            <el-select v-model="Moder.OSClass" style="width:100%" placeholder="请选择适用系统">
              <el-option label="Windows" value="Windows"></el-option>
              <!-- <el-option  label="Mac" value="Mac"></el-option>
            <el-option  label="Android" value="Android"></el-option>
            <el-option  label="Linux" value="Linux"></el-option> -->
              <el-option label="Other" value="Other"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label='系统类型：' prop="OSType">
            <el-select v-model="Moder.OSType" style="width:100%" placeholder="请选择系统类型">
              <el-option label="全部" value=""></el-option>
              <el-option label="64" value="64"></el-option>
              <el-option label="32" value="32"></el-option>
            </el-select>
          </el-form-item>
          <el-form-item label="软件描述：" prop="Descp">
            <el-input placeholder="请输入软件描述" type="textarea" maxlength="50" :rows="3" v-model="Moder.Descp"></el-input>
          </el-form-item>
          <el-form-item label='上传软件：' v-show="Action === 1">
            <el-upload class="upload-demo" action="#" multiple ref="upload" :on-change="filechange"
              :http-request="uploadFileChange" :on-preview="handlePreview" :on-remove="handleRemove"
              :before-remove="beforeRemove" :limit="1" :on-exceed="handleExceed" :disabled="Action === 2"
              :file-list="fileList">
              <el-button size="small" type="primary" :disabled="Action === 2"  @click="checkBeforeClick">点击上传</el-button>
            </el-upload>
          </el-form-item>
        </el-row>
      </el-form>
      <el-divider></el-divider>
      <span slot="footer" class="dialog-footer">
        <el-button type="primary" @click="submit()">确 定</el-button>
        <el-button type="info" @click="moderVisible = false">取 消</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import Cookies from 'js-cookie'
import { connrequest, uploadfile, downloadfile } from '@/api/firstPage'
import { formatBytes, parseTime } from "@/utils/index.js";
import { getToken } from '@/utils/auth' // get token from cookie
import elDragDialog from "@/directive/el-drag-dialog";
import partitionTree from "@/components/partitionTree";
export default {
  directives: { elDragDialog },
  components: {
    partitionTree
  },
  data() {
    return {
      pageNum: 1,
      pageSize: 10,
      total: 0,
      containerWidth: 'calc(100% - 275px)',
      FileUUID: '',
      tableData: [],
      nodeData: [],
      defaultProps: {
        children: 'Class',
        label: 'Name',
        Count: 'Count'
      },
      Attach: {},
      fileList: [],
      Action: 1,
      Moder: {},
      moderVisible: false,
      reSource: [],
      partitionList: [],
      rules: {
        Name: [
          { required: true, message: '请输入软件名称', trigger: 'blur' }
        ],
        Class: [
          { required: true, message: '请选择软件分类', trigger: 'change' }
        ]
      }
    }
  },
  //生命周期 - 创建完成（访问当前this实例）
  created() {
    this.pageSize = (Cookies.get('Zhuoguan_DefaultPageLength') || 10) * 1;

    this.getData()
  },
  //生命周期 - 挂载完成（访问DOM元素）
  mounted() {
  },
  methods: {
    async getData() {
      const res = await connrequest('GetDictSoftwareTree')
      let partitionList = []
      res.Data.Name = `${res.Data.RootName}(${res.Data.Count})` //因为后端返回的所有分区名字叫RootName，子菜单又叫Name, 这里做个转换
      res.Data.disabled = true
      res.Data.Class.map(item => {
        partitionList.push(item)
      })
      this.nodeData = [res.Data]
      this.partitionList = partitionList
      this.GetDictArea(this.PrimName)
    },
    async GetDictArea(Name) {
      const data = {
        Paging: {
          QueryPageNo: this.pageNum,
          QueryPageLength: this.pageSize
        },
        Filter: {
          Name: Name || ''
        }
      }
      const res = await connrequest('GetDictSoftware', data)
      if (res.Data.length === 0 && this.pageNum > 1) {
        this.pageNum--
        this.GetDictArea();
      } else {
        this.tableData = res.Data
        this.total = res.Paging.TotalCount
      }
      if (Name === '' || Name === undefined) {  //获取所有编码
        let partitionNumber = []
        res.Data.map(item => {
          item.FileSizeNum = item.FileSize  //保留原始软件大小的值，修改的时候用
          item.FileSize = item.FileSize ? formatBytes(item.FileSize) : 0
          partitionNumber.push(item.AreaCode)
        })
        this.partitionNumber = partitionNumber
      }
    },
    handleNodeClick(nodeData) {
      const { data } = nodeData
      let PrimName = data.Name.includes('所有软件') ? '' : data.Name
      this.PrimName = PrimName
      this.$set(this.Moder, 'Class', PrimName)
      this.GetDictArea(PrimName)
    },
    async submitTemplete(node) {
      const data = {
        Data: {
          Action: node.Action,
          Detail: {
            Name: node.DepartmentName
          }
        }
      }
      const res = await connrequest('EditDictSoftwareTree', data)
      if (res.Status.StatusCode === 0) {
        this.$message.success(node.Action === 1 ? '新增成功' : '修改成功')
        this.$refs.partitionTree.departmentDialog = false
        this.getData()
      }
    },
    async deleteNode(node) {
      if (node.Count > 0) {
        this.$message.error('该分类下还有数据，请清空后再删除')
        return
      }
      const data = {
        Data: {
          Action: 3,
          Detail: {
            Name: node.Name
          }
        }
      }
      const res = await connrequest('EditDictSoftwareTree', data)
      if (res.Status.StatusCode === 0) {
        this.$message.success('删除成功')
        this.getData()
      }
    },
    addModer() {
      this.Action = 1
      this.Moder = {
        Class: this.PrimName ? this.PrimName : this.partitionList[0]?.Name,
        OSType: '',
        OSClass: 'Windows'
      }
      this.$nextTick(() => {
        this.Attach = []
        this.fileList = []
        this.$refs.Moder.clearValidate();
      })
      this.moderVisible = true
    },
    changeModer(row) {
      this.Action = 2
      this.Moder = { ...row }
      this.FileUUID = row.FileUUID
      if (row.Attach?.length > 0) {
        row.Attach.map(item => {
          item.name = item.OrigFileName
          return item
        })
      }
      this.Attach = row.Attach || []
      this.fileList = row.Attach || []
      this.moderVisible = true
    },
    deleteModer(row) {
      this.$confirm('此操作将永久删除该软件, 是否继续?', '提示', {
        confirmButtonText: '确定',
        cancelButtonText: '取消',
        type: 'warning'
      }).then(async () => {
        const data = {
          Data: {
            Action: 3,
            Detail: { ...row }
          }
        }
        const res = await connrequest('EditDictSoftware', data)
        if (res.Status.StatusCode === 0) {
          this.$message({
            type: 'success',
            message: '删除成功!'
          });
          this.getData()
        }
      }).catch(() => {
        this.$message({
          type: 'info',
          message: '已取消删除'
        });
      });
    },
    async downloadModer(row) {
      let loadingInstance = null;
      try {
        // 确保必要的数据存在
        if (!row.FileUUID || !row.OrigFileName) {
          this.$message.error('文件信息不完整，无法下载');
          return;
        }
        // 打开全局 loading
        loadingInstance = this.$loading({
          lock: true,
          text: '正在下载文件，请稍候...',
          spinner: 'el-icon-loading',
          background: 'rgba(0, 0, 0, 0.7)'
        });
        // 构造下载链接，添加时间戳
        const downloadUrl = `${process.env.VUE_APP_BASE_API}/software_dict/${row.FileUUID}?t=${Date.now()}`;
        // 使用 fetch 获取文件流
        const response = await fetch(downloadUrl, {
          method: 'GET',
          headers: {
            'Cache-Control': 'no-cache' // 避免缓存
          }
        });
        // 检查响应是否成功
        if (!response.ok) {
          throw new Error(`下载失败，状态码: ${response.status}`);
        }
        // 获取文件流并转为 Blob
        const blob = await response.blob();
        // 创建临时 URL 并触发下载
        const url = window.URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.style.display = 'none';
        a.href = url;
        a.download = row.OrigFileName;
        document.body.appendChild(a);
        a.click();
        // 清理
        document.body.removeChild(a);
        window.URL.revokeObjectURL(url);
      } catch (error) {
        this.$message.error('下载失败，请检查网络或稍后重试');
      } finally {
        // 关闭 loading
        if (loadingInstance) loadingInstance.close();
      }
    },
    async submit() {
      this.$refs['Moder'].validate(async (valid) => {
        if (valid) {
          if (this.Attach.length !== 1 && this.Action === 1) {
            this.$message.error('请上传软件')
            return false
          }
          const data = {
            Data: {
              Action: this.Action,
              Detail: {
                ...this.Moder,
                FileUUID: this.FileUUID,
                FileSize: this.Action === 1 ? this.FileSize : this.Moder.FileSizeNum,
                OrigFileName: this.Action === 1 ? this.Attach[0]?.OrigFileName : this.Moder.OrigFileName
              }
            }
          }
          const res = await connrequest('EditDictSoftware', data)
          if (res.Status.StatusCode === 0) {
            this.$message.success(this.Action === 1 ? '新增成功' : '修改成功')
            this.moderVisible = false
            this.getData()
          }
        }
      })
    },
    toggleVisibility(isHidden) {
      if (isHidden)
        this.containerWidth = '100%';
      else
        this.containerWidth = 'calc(100% - 275px)';
    },
    filechange(file, fileList) {
      let arr = []
      fileList.map(item => {
        arr.push({ OrigFileName: item.name })
      })
      this.Attach = arr
    },
    async uploadFileChange(file) {
      const MAX_SIZE = 2 * 1024 * 1024 * 1024; // 2GB in bytes
      // 检查文件大小
      if (file.file.size > MAX_SIZE) {
        this.$message.error('文件大小超过限制（最大 2GB）');
        return;
      }
      // 构造 FormData
      let formData = new FormData();
      formData.append('CmdCode', "UploadFileToTmp");
      formData.append('file', file.file);
      // 发送上传请求
      const res = await uploadfile(formData);
      if (res.Status.StatusCode === 0) {
        this.FileSize = file.file.size;
        this.FileUUID = res.Data.UUID;
        this.$message.success('文件上传成功');
      }
    },
    handlePreview() { },
    async handleRemove(file, fileList) {
      const data = {
        Data: {
          FileUUID: file.uid
        }
      }
      const res = await connrequest('DeleteSoftwareDictAttach', data)
      if (res.Status.StatusCode === 0) {
        this.Attach = this.Attach.filter(item => item.uid !== file.uid);
        this.FileSize = 0
        this.$message.success('文件删除成功')
      }
    },
    beforeRemove(file, fileList) {
      return this.$confirm(`确定移除 ${file.name}？`);
    },
    handleExceed(files, fileList) {
      this.$message.warning(`当前限制选择 1 个文件，本次选择了 ${files.length} 个文件，共选择了 ${files.length + fileList.length} 个文件`);
    },
    checkBeforeClick(e) {
      if (this.$isFromCenter) {
        e.stopPropagation(); // 阻止 el-upload 弹出选择框
        this.$message.error('当前模式不支持上传文件')
        return
      }
    },
    handleSizeChange(pageSize) {
      this.pageSize = pageSize
      this.pageNum = 1
      this.getData()
    },
    handleCurrentChange(pageNum) {
      this.pageNum = pageNum
      this.getData()
    }
  }
};
</script>
<style scoped>
.box {
  background-color: lightblue;
  transition: width 0.5s;
  /* 添加过渡动画 */
}
</style>
